package com.usermanage.SecurityConfig;

import com.usermanage.ExceptionConfig.MyException;
import com.usermanage.Mapping.UserMapping;
import com.usermanage.Service.UserService;
import com.usermanage.util.StaticUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.filter.CharacterEncodingFilter;

/**
 * Created by 過客 on 2018/3/9
 */
@Slf4j
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserMapping userMapping;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        encodingFilter.setForceEncoding(true);
        http.addFilterBefore(encodingFilter, CsrfFilter.class);//加载字符过滤集
        http.headers().frameOptions().disable();//不允许加载iframe问题解决
        //取消csrf验证
        http.csrf().disable();
        http.sessionManagement().invalidSessionUrl(StaticUtil.EOSIP);
//        http.sessionManagement().invalidSessionUrl("/session/invalid");
        http.authorizeRequests()
//                .antMatchers("/home").permitAll()//访问：/home 无需登录认证权限
//                .anyRequest().authenticated() //其他所有资源都需要认证，登陆后访问

                .antMatchers("/tariffModifyController/**").authenticated()
                .antMatchers("/tariffController/**").authenticated()
                .antMatchers("/contractModifyController/**").authenticated()
                .antMatchers("/message/in/insert.json").authenticated()
                .antMatchers("/company/**").authenticated()
//                .antMatchers("/wuliu/**").authenticated()
                .antMatchers("/project/**").authenticated()
//                .antMatchers("/message/internal/**").authenticated()
                .antMatchers("/contract/**").authenticated()
                .antMatchers("/group/**").authenticated()
                .antMatchers("/order/**").authenticated()
                .antMatchers("/pmOrder/**").authenticated()
                .antMatchers("/permission/**").authenticated()
                .antMatchers("/role/**").authenticated()
                .antMatchers("/sales/**").authenticated()
                .antMatchers("/shopping/**").authenticated()
                .antMatchers("/user/**").authenticated()
                .antMatchers("/userCenter/**").authenticated()
                .antMatchers("/index.page").authenticated()


//                .antMatchers("/user/**").hasRole("1,9") //登陆后之后拥有“ADMIN”权限才可以访问，否则系统会出现“403”权限不足的提示
                .and()
                .formLogin()
                .loginPage("/login") //指定登陆页面
                .defaultSuccessUrl("/index.page", false)
//                .failureForwardUrl("/logOut?error=true")
                .successHandler(authenticationSuccessHandler())
                .failureHandler(authenticationFailureHandler())
                .and()
                .logout()
                .logoutSuccessUrl(StaticUtil.EOSIP) //退出登录后的默认路径
                .permitAll()

//                .invalidateHttpSession(true)
                .and()
                .exceptionHandling()
                .accessDeniedHandler(authenticationAccessDeniedHandler());
//                .rememberMe()//登录后记住用户，下次自动登录,数据库中必须存在名为persistent_logins的表
//                .tokenValiditySeconds(1209600);
    }

    @Override
    //配置用户管理服务
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        auth.authenticationProvider(provider);
        auth.eraseCredentials(false);
//        auth.inMemoryAuthentication()
//                .passwordEncoder(passwordEncoder());
//        provider.setHideUserNotFoundExceptions(false);
        provider.setUserDetailsService(new MyUserDetailService(userMapping));
    }

    /**
     * 定义登陆成功返回类
     *
     * @return
     */
    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler() {
        MySimpleUrlAuthenticationSuccessHandler loginSuccessHandler = new MySimpleUrlAuthenticationSuccessHandler();
        return loginSuccessHandler;
    }
    /**
     * 定义登陆失败返回类
     * @return
     */
    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        MySimpleUrlAuthenticationFailureHandler loginFailureHandler = new MySimpleUrlAuthenticationFailureHandler();
        return loginFailureHandler;
    }

    /**
     * 定义登陆失败返回类
     * @return
     */
    @Bean
    public AccessDeniedHandler authenticationAccessDeniedHandler() {
        AuthenticationAccessDeniedHandler accessDeniedHandler = new AuthenticationAccessDeniedHandler();
        return accessDeniedHandler;
    }

    /**
     * 密码加密
     * @return
     */
    @Bean
    public MyPasswordEncoder passwordEncoder() {
        return new MyPasswordEncoder();
    }


    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

//    @Bean
//    @Override
//    public UserDetailsService userDetailsServiceBean() throws Exception {
//        return super.userDetailsServiceBean();
//    }
}
